/**
 * 入参typeStatus:1新增，2编辑，3查看 ；id:编辑查看 传入id
 *
 * */
import React, { PureComponent } from 'react';
import { connect } from 'dva';
import { Form, Icon as LegacyIcon } from '@ant-design/compatible';
import '@ant-design/compatible/assets/index.css';
import { Popover, Spin, message, Modal } from 'antd';
import moment from 'moment';
import 'moment/locale/zh-cn';
import { FirstHeaderC, PrimaryC, PrimaryGhostC, FixedButtonC, SecondHeaderC } from '../../../../comps';
import '../index.less';
import FormTableC from './formTableC';
import ImportFileC from './importFileC';
import GroupC from './groupC';
import InitFormC from './InitFormC';
import RiskC from './riskC';
import { exportFile } from '@/src/utils/commonFunc';
import uuid from 'es6-uuid';

@connect(({ portfolioOptimizationM, loading }) => ({
  portfolioOptimizationM,
  loading,
}))
@Form.create()
export default class SettingC extends PureComponent {
  state = {
    timeOutGap: 500,
    currentPage: 1, // news当前页码
    numInPage: 10, // 每页数量
    isShowExample: false, // 是否显示示例组合
    isShowWeight: false, // 是否显示配置权重
    initColumns: [
      {
        // 默认表头
        key: 'asset',
        title: '资产',
        isNeed: true,
      },
      {
        key: 'initWeight',
        title: '初始权重(%)',
        isNeed: true,
      },
      {
        key: 'expectReturn',
        title: '预期收益率(%)',
        isNeed: false,
      },
      {
        key: 'expectVolatility',
        title: '预期波动率(%)',
        isNeed: false,
      },
      {
        key: 'weightBottom',
        title: '权重下界(%)',
        isNeed: false,
      },
      {
        key: 'weightTop',
        title: '权重上界(%)',
        isNeed: false,
      },
      {
        key: 'group',
        title: '组别',
        isNeed: false,
      },
    ],
    weightMethodList: [
      // 配置权重
      { title: '等权重', value: '0', isSelect: false },
      { title: '归一化', value: '1', isSelect: false },
      { title: '清空', value: '2', isSelect: false },
    ],
    visible: false, // 展示导入组合
    groupVisible: false, // 展示分组约束
    groupData: [], // 分组约束列表数据
    rangedate: [moment().subtract(1, 'years'), moment().subtract(1, 'days')],
    riskArgs: undefined, // 风险约束的查询条件
    barraConst: '0', // 默认barra 所以有风险约束0  1否
    portfolioName: undefined, // 组合名称 导入的或者示例组合的名称
  };

  UNSAFE_componentWillMount() {
    this.originData = _.cloneDeep(this.state);
  }

  componentDidMount() {
    const { initColumns } = this.state;
    // 查询示例组合列表
    this.props.dispatch({
      type: 'portfolioOptimizationM/getSamplePortList',
      payload: {},
      callback: (msg, data) => {
        if (msg == 'success') {
          this.setState({
            exampleList: [...data],
          });
        } else {
          this.setState({
            exampleList: [],
          });
        }
      },
    });
    if (this.props.typeStatus != 1) {
      // 查询回填数据
      this.props.dispatch({
        type: 'portfolioOptimizationM/querySettingById',
        payload: { id: this.props.id },
        callback: (data) => {
          this.getImportData(data, 'detail'); // 设置回填参数
          if (data.barraConst == '0' && data.barraData) {
            // barra风险因子回填
            const arr = data.barraData?.dataSource || [];
            arr.map((item) => {
              item.key = uuid(16);
            });
            this.riskRef?.setState({ dataSource: [...arr] });
          }
        },
      });
    }
  }

  componentWillUnmount() {
    // 离开前清除models数据
  }

  // 切换列表是否下拉表格变化
  handleSelectChange = (e, type) => {
    const { initColumns } = this.state;
    if (type == 'barraConst') {
      // 当选择“是”时，下方出现【风险因子约束设置】
      this.setState({
        barraConst: e,
      });
      if (e == '1')
        this.setState({
          // 清空条件 否的时候
          riskArgs: e,
        });
      return;
    }
    initColumns.map((item) => {
      // 决定是否显示该列
      if (type == 'assetConst') {
        if (item.key == 'weightBottom') {
          item.isNeed = e == '0';
        }
        if (item.key == 'weightTop') {
          item.isNeed = e == '0';
        }
      } else if (item.key == type) {
        item.isNeed = e == '0';
      }
    });
    this.setState({
      initColumns: [...initColumns],
    });
  };

  // 相关设置 权重 示例 点击按钮 更新选中颜色
  handleClick = (val, type) => {
    const { weightMethodList, exampleList } = this.state;
    if (type == 'weight') {
      weightMethodList.map((item) => {
        if (item.value == val) {
          item.isSelect = true;
        } else {
          item.isSelect = false;
        }
      });
      this.setState({
        weightMethodList: [...weightMethodList],
      });
      this.child.setWeightBytype(val);
    } else {
      let title;
      exampleList.map((item) => {
        if (item.value == val) {
          item.isSelect = true;
          title = item.title;
        } else {
          item.isSelect = false;
        }
      });
      this.setState({
        exampleList: [...exampleList],
        disabledBarra: false,
      });
      // 获取示例组合对应的表格数据
      this.props.dispatch({
        type: 'portfolioOptimizationM/getSamplePortTable',
        payload: {
          id: val,
        },
        callback: (msg, data) => {
          if (msg == 'success') {
            this.setState({
              portfolioName: title,
            });
            const tableData = [];
            let sum = 0;
            data.map((item, index) => {
              tableData.push({
                order: index + 1,
                asset: {
                  value: item.asset,
                  label: item.title,
                  key: item.asset,
                },
                initWeight: item.initWeight,
              });
              sum += item.initWeight;
            });
            tableData.push({ order: '总计', initWeight: sum });
            this.child.setState({
              dataSource: tableData,
            });
          }
        },
      });
    }
  };

  // 提交 执行分析按钮
  submit = () => {
    const { dispatch, type } = this.props;
    const { initColumns, groupData, riskArgs } = this.state;
    const arr = this.child.submit();
    const values = this.initFormRef.submit();
    let barraData = {};
    if (values?.barraConst == '0') {
      // 有风险因子约束
      const riskData = this.riskRef.submit();
      if (riskData == undefined) message.warning('请点击“刷新”得到最新的风格因子暴露度值');
      if (!arr || !riskData || !values) return; // 校验config表单数据，及表格数据
      const arrRisk = riskData.map((item) => {
        return {
          factorName: item.factorName,
          exposureBottom: item.exposureBottom,
          exposureTop: item.exposureTop,
          exposureInit: item.exposureInit,
          factorCnName: item.factorCnName,
        };
      });
      barraData = {
        dataSource: arrRisk,
        columns: [
          {
            key: 'factorName',
            title: '风险因子',
          },
          {
            key: 'exposureBottom',
            title: '暴露度下界(%)',
          },
          {
            key: 'exposureTop',
            title: '暴露度上界(%)',
          },
        ],
      };
    } else {
      if (!arr || !values) return; // 校验config表单数据，及表格数据
    }

    const tempData = JSON.parse(JSON.stringify(arr.slice(0, arr.length - 1)));
    const configData = tempData.filter((item) => item.asset);
    configData.map((item) => {
      // 因为导入的原因  设置了labelInValue 所以提交之前做下处理
      const asset = item.asset.key;
      item.title = item.asset.label;
      item.asset = asset;
      delete item.order;
      delete item.isRed;
    });
    if (!values.portfolioName) values.portfolioName = this.state.portfolioName; // 如果表单没有选择组合名称
    const payload = {
      id: this.props.id, // 编辑时候提交
      type,
      configData: {
        columns: initColumns.filter((item) => item.isNeed),
        dataSource: [...configData],
      },
      ...values,
      beginDate: values.beginDate.format('YYYY-MM-DD'),
      groupData: {
        dataSource: [...groupData],
        columns: [
          {
            // 默认表头
            key: 'group',
            title: '组名',
          },
          {
            key: 'weightBottom',
            title: '权重下界(%)',
          },
          {
            key: 'weightTop',
            title: '权重上界(%)',
          },
        ],
      },
    };
    if (type == '0') {
      if (!values.beginDate || !values.endDate) return;
      if (values.rollBacktest !== '0') delete values.freq; // 滚动回测为否 则频率不选
      payload.endDate = values.endDate.format('YYYY-MM-DD');
      if (payload.barraConst == '0') {
        // barra因子下 组合 基准 持仓设置有变动 必须重新点击刷新按钮获取最新的风格因子暴露度值
        payload.barraData = barraData;
        // console.log(riskArgs)
        for (const key in riskArgs) {
          if (JSON.stringify(riskArgs[key]) != JSON.stringify(payload[key])) {
            message.warning('组合、业绩比较基准、持仓设置有变动,必须点击刷新按钮获取最新的风格因子暴露度值！');
            return;
          }
        }
      }
    }

    dispatch({
      type: 'portfolioOptimizationM/executeOptimization1',
      payload,
      callback: (data) => {
        if (data) {
          // 提交成功 页面弹窗提示
          if (data != 1) this.reset(); // 没有结果的时候 可以不刷新

          Modal.info({
            content: data == 1 ? '当前参数配置下，无优化结果，请调整参数' : '优化完成，可点击【查看分析结果】进行查看',
            okText: '确定',
          });
          if (this.props.typeStatus != 1) {
            this.props.changeStatus('1', '1');
          }
        }
      },
    });
  };

  // 重置reset
  reset = () => {
    this.flag = true;
    this.initFormRef.reset(); // 重置表单
    const { exampleList } = this.state;
    exampleList.map((item) => (item.isSelect = false)); // 示例组合 配色重置
    this.setState({ ..._.cloneDeep(this.originData) });
    sessionStorage.removeItem('isShowTitle'); // 展示组合优化标题
    this.child.reset(); // 清空表格数据
    this.childGroup.reset(); // 清空分组约束数据
    if (this.riskRef) this.riskRef.reset(); // 清空风险
  };

  // getImportData 获取导入的数据，替换页面上的数据
  getImportData = (data, type) => {
    if (type == 'detail') {
      this.initFormRef.settingDetails(data); // 参数回填
      this.initFormRef.portfolioChange({ key: data.portfolio });
      // 持仓表头和设置联调 资产约束 预期收益率 分组约束
      this.handleSelectChange(`${data.assetConst}`, 'assetConst');
      this.handleSelectChange(`${data.groupConst}`, 'group');
      this.handleSelectChange(`${data.expectReturn}`, 'expectReturn');
    }
    this.setState({
      // 保存回填和导入的名称
      portfolioName: data.portfolioName,
    });
    if (data.groupConfigData || data.groupData) {
      const temp = data.groupConfigData || data.groupData;
      const groupData = temp.dataSource.map((item, index) => {
        item.order = index + 1;
        item.id = item.id;
        return item;
      });
      this.childGroup.setState({
        dataSource: [...groupData],
      });
      this.setState({
        // 表格的组别下拉列表
        groupData: [...groupData],
      });
    }
    const configData = [];
    let sum = 0;
    const assetData = data.assetConfigData || data.configData;
    const myData = [];
    assetData &&
      assetData.dataSource.map((item, index) => {
        myData.push(_.cloneDeep(item));
        item.order = index + 1;
        const { title } = item;
        const { asset } = item;
        delete item.title;
        item.asset = {
          key: asset,
          value: asset,
          label: title,
        };
        configData.push(item);
        sum += item.initWeight;
      });
    configData.push({ order: '总计', initWeight: sum });
    this.child.setState({
      dataSource: [...configData],
    });
    // 存储风险因子 查询条件 持仓设置 组合 基准
    if (data.barraConst == '0' && data.barraData)
      this.setState({
        riskArgs: {
          type: this.props.type,
          portfolio: data.portfolio,
          benchmark: data.benchmark,
          configData: {
            columns: this.state.initColumns.filter((item) => item.isNeed),
            dataSource: [...myData],
          },
        },
      });
  };

  // 获取分组约束 对应的组别列表
  getGroupData = (arr) => {
    const groupData = JSON.parse(JSON.stringify(arr));
    this.setState(
      {
        groupData: [...groupData],
      },
      () => {
        const arr = this.child.state.dataSource;
        arr.map((item, index) => {
          // 查找已选择的组别 是否已被删除，删除则置空
          if (index == arr.length - 1) return;

          if (!item.group) return;
          const idList = this.state.groupData.map((group) => {
            return group.id;
          });
          if (!idList.filter((id) => id == item.group).length) {
            delete item.group;
          }
        });
        this.child.setState({
          dataSource: [...arr],
        });
      },
    );
  };

  // 分组约束、相关设置
  setBtnRender = () => {
    const { isShowExample, isShowWeight, weightMethodList, exampleList = [] } = this.state;
    // 相关设置的hover 悬浮框
    const content = (
      <div>
        <div className='relativeSet'>
          <p
            onClick={() => {
              if (!exampleList.length) return;
              this.setState({ isShowExample: !isShowExample });
            }}
          >
            <LegacyIcon type={isShowExample == false ? 'caret-right' : 'caret-down'} style={{ cursor: exampleList.length ? 'inherit' : 'not-allowed' }} />
            示例组合
          </p>
          <ul style={{ display: isShowExample == true ? 'block' : 'none' }}>
            {exampleList &&
              exampleList.map((item, key) => {
                return (
                  <li
                    key={key}
                    value={item.value}
                    className={item.isSelect == true ? 'selectColor' : ''}
                    onClick={() => {
                      this.handleClick(item.value, 'example');
                    }}
                  >
                    {item.title}
                  </li>
                );
              })}
          </ul>
        </div>
        <div className='relativeSet'>
          <p
            onClick={() => {
              this.setState({ isShowWeight: !isShowWeight });
            }}
          >
            <LegacyIcon type={isShowWeight == false ? 'caret-right' : 'caret-down'} />
            配置权重
          </p>
          <ul style={{ display: isShowWeight == true ? 'block' : 'none' }}>
            {weightMethodList.map((item, key) => {
              return (
                <li
                  key={key}
                  value={item.value}
                  className={item.isSelect == true ? 'selectColor' : ''}
                  onClick={() => {
                    this.handleClick(item.value, 'weight');
                  }}
                >
                  {item.title}
                </li>
              );
            })}
          </ul>
        </div>
      </div>
    );
    return (
      <div className='setBtn' style={{ textAlign: this.props.type == 0 ? 'left' : 'right' }}>
        {this.props.type == 1 ? (
          <PrimaryGhostC
            title='分组约束'
            onClick={() => {
              this.setState({ groupVisible: true });
            }}
          />
        ) : (
          <PrimaryC
            title='分组约束'
            onClick={() => {
              this.setState({ groupVisible: true });
            }}
          />
        )}
        <Popover placement='bottomRight' trigger='click' content={content}>
          <div>
            <PrimaryGhostC title='相关设置' />
          </div>
        </Popover>
      </div>
    );
  };

  export = (e) => {
    // 模板下载
    if (this.props.type == '0') {
      exportFile('api/v1/bondTrade/download-template', { fileName: 'portOptimizationTemplate_stock.xlsx' });
    } else if (this.props.type == '1') {
      exportFile('api/v1/bondTrade/download-template', { fileName: 'portOptimizationTemplate_bond.xlsx' });
    }
  };

  // 查询风险因子
  queryRisk = () => {
    const { initColumns, groupData } = this.state;
    const arr = this.child.submit();
    if (!arr) {
      // 校验持仓设置的数据 是否ok
      message.destroy();
      message.warning('请完善持仓设置数据！');
      return;
    }
    let values;
    this.initFormRef.props.form.validateFields(['benchmark', 'portfolio'], (err, vals) => {
      if (err) {
        message.destroy();
        message.warning('请选择业绩比较基准！');
      } else {
        values = vals;
      }
    });
    if (values) {
      const tempData = JSON.parse(JSON.stringify(arr.slice(0, arr.length - 1)));
      const configData = tempData.filter((item) => item.asset);
      configData.map((item) => {
        // 因为导入的原因  设置了labelInValue 所以提交之前做下处理
        const asset = item.asset.key;
        item.title = item.asset.label;
        item.asset = asset;
        delete item.order;
        delete item.isRed;
      });
      this.setState({
        riskArgs: {
          type: this.props.type,
          portfolio: values.portfolio,
          benchmark: values.benchmark,
          configData: {
            columns: initColumns.filter((item) => item.isNeed),
            dataSource: [...configData],
          },
        },
      });
    }
  };

  renderContent = () => {
    const { loading, typeStatus } = this.props;
    const { groupData, initColumns, barraConst } = this.state;
    return (
      <div>
        <Spin spinning={loading.effects['portfolioOptimizationM/executeOptimization1'] == true}>
          <div className={'config'}>
            {typeStatus != '3' && (
              <div style={{ marginBottom: '11px' }}>
                <ImportFileC getImportData={this.getImportData} />
                <a
                  onClick={() => {
                    this.export();
                  }}
                  style={{ verticalAlign: 'bottom', marginLeft: '10px' }}
                >
                  {this.props.type == '0' ? '股票模板' : this.props.type == '1' ? '债券模板' : ''}
                </a>
              </div>
            )}
            <InitFormC
              typeStatus={typeStatus}
              onRef={(ref) => {
                this.initFormRef = ref;
              }}
              type={this.props.type}
              handleSelectChange={this.handleSelectChange}
            />
            <SecondHeaderC title='持仓设置' />
            {typeStatus != '3' && this.setBtnRender()}
            <FormTableC
              typeStatus={typeStatus}
              barraConst={barraConst}
              type={this.props.type}
              initColumns={initColumns}
              groupData={groupData}
              onRef={(ref) => {
                this.child = ref;
              }}
            />
            <GroupC
              onRef={(ref) => {
                this.childGroup = ref;
              }}
              visible={this.state.groupVisible}
              triggleVisible={(e) => {
                this.setState({ groupVisible: e });
              }}
              getGroupData={this.getGroupData}
              oldData={this.state.groupData}
            />
            {this.state.barraConst == '0' && (
              <>
                <SecondHeaderC title='风险因子约束' />
                {typeStatus != '3' && (
                  <PrimaryC style={{ marginBottom: '10px' }} onClick={this.queryRisk} title={'刷新'} helper='权重调整后，点击“刷新”得到最新的风格因子暴露度值' />
                )}
                <RiskC
                  typeStatus={typeStatus}
                  riskArgs={this.state.riskArgs}
                  onRef={(ref) => {
                    this.riskRef = ref;
                  }}
                />
              </>
            )}
          </div>
        </Spin>
      </div>
    );
  };

  render() {
    const { loading, typeStatus } = this.props;
    return (
      <div>
        <FixedButtonC
          topHtml={this.renderContent()}
          bottomHtml={
            <div style={{ width: '100%' }}>
              {typeStatus == '1' && (
                <div className={'footerBtn'}>
                  <span
                    className={'mainColor'}
                    onClick={() => {
                      this.props.changeStatus('2');
                    }}
                  >
                    查看分析结果
                  </span>
                  <PrimaryC loading={loading.effects['portfolioOptimizationM/executeOptimization1'] == true} title='提交' onClick={this.submit} />
                  <PrimaryGhostC title='重置' onClick={this.reset} />
                </div>
              )}
              {typeStatus == '2' && (
                <PrimaryC loading={loading.effects['portfolioOptimizationM/executeOptimization1'] == true} style={{ marginRight: '15px' }} title='提交' onClick={this.submit} />
              )}
              {typeStatus != '1' && (
                <PrimaryGhostC
                  title='取消'
                  onClick={() => {
                    this.props.changeStatus('2');
                  }}
                />
              )}
            </div>
          }
        />
      </div>
    );
  }
}
